package Dashboard;

import java.awt.Button;
import java.awt.Choice;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Rectangle;
import java.awt.TextField;

import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

import UserInput.DashboardInput;
import UserInput.Joystick;
import UserInput.KeyboardInput;
import UserInput.UserInput;

import Command.Command;
import Gauges.Gauges;

/**
 * This class is the Frame of the Dashboard and as such extends JFrame
 * 
 * @author Sietse
 */
public class DashboardFrame extends JFrame
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1966294278426796285L;
	//The dashboardview - a panel in which all images will be painted
	private DashboardView dashboardView;
	private Dimension screenSize;

	private Button connectButton;
	private Button newSessionButton;
	private Choice chooseFrequencyBox;
	private Button startReplayButton;
	private Choice chooseReplayBox;
	private Button resetDatabaseButton;
	private TextField commandListBox;

	// Userinput
	private ArrayList<UserInput> arrUserInput = new ArrayList<UserInput>();

	/**
	 * Sets the basic functionality of the frame
	 * and initializes the menu and dashboardview
	 */
	public DashboardFrame() 
	{
		super("Dashboard");	

		screenSize = Toolkit.getDefaultToolkit().getScreenSize();

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setIconImage(new ImageIcon("src/Resources/images/SailRack.JPG").getImage());
		this.setLayout(null);   
	
		initMenu();
		initDashboardView();

		this.setSize(screenSize.width, screenSize.height);
		this.setExtendedState(Frame.MAXIMIZED_BOTH);
		this.setVisible(true);
		setFocusable(true);
	}

	/**
	 * Puts the specified strings into commandListBox
	 * @param p_strCommand a string representing the command
	 * @param p_cmdCommand the command itself
	 */
	public void writeLineToBox(String p_strCommand, Command p_cmdCommand)
	{
		commandListBox.setText(Command.class.getCanonicalName() + " - " + p_strCommand + "\n");
	}

	/**
	 * Initialize the menu with all its buttons and boxes
	 */
	private void initMenu()
	{
		//Initialize
		connectButton = new Button("Connect BT");
		newSessionButton = new Button("New Session");
		chooseFrequencyBox = new Choice();
		startReplayButton = new Button("Start Replay");
		chooseReplayBox = new Choice();
		resetDatabaseButton = new Button("Reset Database");
		commandListBox = new TextField();
		commandListBox.setEditable(false);
		
		//Set the frequency options
		chooseFrequencyBox.add("1x");
		chooseFrequencyBox.add("2x");
		chooseFrequencyBox.add("10x");
		chooseFrequencyBox.add("100x");

		//Give them a name
		connectButton.setName(String.valueOf(MenuNames.CONNECT));
		newSessionButton.setName(String.valueOf(MenuNames.NEWSESSION));
		chooseFrequencyBox.setName(String.valueOf(MenuNames.CHOOSEFREQUENCY));
		startReplayButton.setName(String.valueOf(MenuNames.STARTREPLAY));
		chooseReplayBox.setName(String.valueOf(MenuNames.CHOOSEREPLAY));
		resetDatabaseButton.setName(String.valueOf(MenuNames.RESETDATABASE));
		commandListBox.setName(String.valueOf(MenuNames.COMMANDLIST));

		//Put them in the right place
		int x = 0;
		connectButton.setBounds(x, 0, 100, 20);
		x += 100;
		newSessionButton.setBounds(x, 0, 150, 20);
		x += 150;
		chooseFrequencyBox.setBounds(x, 0, 100, 20);
		x += 100;
		startReplayButton.setBounds(x, 0, 150, 20);
		x += 150;
		chooseReplayBox.setBounds(x, 0, 100, 20);
		x += 100;
		resetDatabaseButton.setBounds(x, 0, 150, 20);
		x += 150;
		commandListBox.setBounds(x, 0, screenSize.width, 20);
		
		/**
		 * set 'no focus' to buttons!
		 */
		connectButton.setFocusable(false);
		newSessionButton.setFocusable(false);
		chooseFrequencyBox.setFocusable(false);
		startReplayButton.setFocusable(false);
		chooseReplayBox.setFocusable(false);
		commandListBox.setFocusable(false);
		resetDatabaseButton.setFocusable(false);

		//Add them to the frame
		this.add(connectButton);
		this.add(newSessionButton);
		this.add(chooseFrequencyBox);
		this.add(startReplayButton);
		this.add(chooseReplayBox);
		this.add(resetDatabaseButton);
		this.add(commandListBox);
	}
	
	/**
	 * Link the ItemListener to the widgets requiring this type of listener
	 * @param listener the ItemListener
	 */
	private void linkItemListener(ItemListener listener)
	{
		chooseReplayBox.addItemListener(listener);
	}

	/**
	 * Link the ActionListener to the widgets requiring this type of listener
	 * @param listener the ActionListener
	 */
	private void linkActionListener(ActionListener listener)
	{
		connectButton.addActionListener(listener);
		newSessionButton.addActionListener(listener);
		startReplayButton.addActionListener(listener);
		resetDatabaseButton.addActionListener(listener);
	}

	/**
	 * Populate the list of replays
	 * @param sessionList a list of sessions from the database
	 */
	public void populateReplayList(ArrayList<Integer> sessionList)
	{
		chooseReplayBox.removeAll();
		for(Integer replay : sessionList)
		{
			chooseReplayBox.addItem(String.valueOf(replay));
		}
	}

	/**
	 * Initializes the DashboardView
	 */
	private void initDashboardView()
	{
		dashboardView = new DashboardView();
		dashboardView.setBounds(0, 21, screenSize.width, screenSize.height); //An offset of 21 pixels for the menu     
		this.getContentPane().add(dashboardView); //Add the view to this frame
		this.pack();
	}


	/**
	 * Update all gauges on the dashboard
	 * @param gaugeList a list of gauges from which the values need to be extracted
	 */
	public void updateGauges(ArrayList<Gauges> gaugeList)
	{	
		for(Gauges gauge : gaugeList)
		{	
			dashboardView.updateGaugeImages(gauge.getName(), gauge.getValue());
		} 

		dashboardView.paintGaugesNow();
	}

	/**
	 * Sets the replaylight on the dashboard
	 * @param value the value the light needs to be set on
	 */
	public void setReplayLight(boolean value)
	{
		dashboardView.setReplayLight(value);
	}

	/**
	 * Ties the InputListeners to the dashboard
	 * @param arrUserInput the list of InputListeners
	 */
	public void addInputListeners(ArrayList<UserInput> p_arrUserInput)
	{
		arrUserInput.addAll(p_arrUserInput);
		
		for(UserInput ui : p_arrUserInput )
		{
			if(ui instanceof KeyboardInput)
			{
				setFocusable(true);
				addKeyListener((KeyboardInput)ui);
			}
			else if(ui instanceof Joystick)
			{
				((Joystick) ui).start();			
			}
			else if(ui instanceof DashboardInput)
			{
				this.linkItemListener((DashboardInput)ui);
				this.linkActionListener((DashboardInput)ui);
				dashboardView.linkMouseListener((DashboardInput) ui);
			}
		}
	}

	public void setBluetoothConnection(int bluetoothConnection) {
		dashboardView.setBluetoothConnection(bluetoothConnection);
		
	}
}
